package xyz.zcq.zcqrpc.springboot.start.bootstrap;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import xyz.zcq.zcqrpc.RpcApplication;
import xyz.zcq.zcqrpc.config.RegistryConfig;
import xyz.zcq.zcqrpc.config.RpcConfig;
import xyz.zcq.zcqrpc.model.ServiceMetaInfo;
import xyz.zcq.zcqrpc.registry.LocalImplRegistry;
import xyz.zcq.zcqrpc.registry.Registry;
import xyz.zcq.zcqrpc.registry.RegistryFactory;
import xyz.zcq.zcqrpc.springboot.start.annotation.RpcServer;

/**
 * Rpc服务提供者引导程序
 */
public class RpcProviderBootstrap implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> beanClass = bean.getClass();
        RpcServer rpcServer = beanClass.getAnnotation(RpcServer.class);
        if (rpcServer != null) {
            Class<?> interfaceClass = rpcServer.interfaceClass();
            if (interfaceClass == void.class) {
                interfaceClass = beanClass.getInterfaces()[0];
            }
            // 注册服务实现到本地
            LocalImplRegistry.register(interfaceClass.getName(), beanClass);
            // 注册服务到注册中心
            RpcConfig rpcConfig = RpcApplication.getRpcConfig();
            RegistryConfig registryConfig = rpcConfig.getRegistryConfig();
            Registry registry = RegistryFactory.getInstance(registryConfig.getRegistry());
            ServiceMetaInfo serviceMetaInfo = new ServiceMetaInfo();
            serviceMetaInfo.setServiceName(interfaceClass.getName());
            serviceMetaInfo.setServiceVersion(rpcServer.serviceVersion());
            serviceMetaInfo.setServiceHost(rpcConfig.getServerHost());
            serviceMetaInfo.setServicePort(rpcConfig.getServerPort());
            try {
                registry.register(serviceMetaInfo);
            } catch (Exception e) {
                throw new RuntimeException(interfaceClass.getName() + " 服务注册失败", e);
            }
        }

        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

}
